import { Injectable, OnModuleInit, OnModuleDestroy, Logger } from '@nestjs/common';
import * as WebSocket from 'ws';
import { Server } from 'ws';
import { IncomingMessage } from 'http';
import { RecordsService } from '../records/records.service';
import { AiService } from '../ai/ai.service';
import { AlarmService } from '../alarm/alarm.service';
import { SessionService } from '../session/session.service';
import { SmsService } from '../sms/sms.service';
import { AliyunChatService } from './chat.service';

@Injectable()
export class ChatGateway implements OnModuleInit, OnModuleDestroy {
  private wss: Server;
  private clients: Map<string, WebSocket> = new Map();
  private clientBuffers: Map<string, string> = new Map();
  private logger = new Logger(ChatGateway.name);

  constructor(
    private readonly chatService: AliyunChatService,
    private readonly recordsService: RecordsService,
    private readonly aiService: AiService,
    private readonly alarmService: AlarmService,
    private readonly sessionService: SessionService,
    private readonly smsService: SmsService,
  ) {}

  onModuleInit() {
    this.wss = new WebSocket.Server({ port: 3001 }, () => {
      this.logger.log('标准 WebSocket 服务器已启动，监听端口 3001');
    });

    this.wss.on('connection', (ws: WebSocket, request: IncomingMessage) => {
      this.logger.log('新的客户端连接');

      const clientId = this.generateClientId();
      this.clients.set(clientId, ws);

      this.sendMessage(clientId, {
        type: 'connection',
        message: '连接成功',
        clientId,
      });

      ws.on('message', (data: Buffer) => {
        this.handleMessage(clientId, data.toString());
      });

      ws.on('close', () => {
        this.logger.log(`客户端 ${clientId} 断开连接`);
        this.clients.delete(clientId);
        this.clientBuffers.delete(clientId);
      });

      ws.on('error', (error) => {
        this.logger.error(`客户端 ${clientId} 错误:`, error);
      });
    });
  }

  private generateClientId(): string {
    return Date.now().toString(36) + Math.random().toString(36).substr(2, 5);
  }

  static parse(content: string): any {
    try {
      return JSON.parse(content);
    } catch (error) {
      throw new Error('Invalid JSON format in content');
    }
  }

  async analyzeWarningThreshold(sessionId: number, content: string) {
    try {
      const s = await this.aiService.askQuestion(
        content,
        '你是一个心理对话监测助手。  \n' +
          '输入为【用户单轮对话文本】。  \n' +
          '\n' +
          '任务：  \n' +
          '1. 如果对话出现**严重负面或危险言语**（如“想结束自己的生命”“我要自杀”“我要杀人”等），输出红色警报=2，并在解释中说明其存在极高风险（例如自杀、自残、暴力等），严重危及生命安全。  \n' +
          '2. 如果对话出现**强烈的回避、否定、自我贬低、绝望**等倾向（如“不想活了”“不想面对任何人”“我很没用”），输出橙色警报=3，并在解释中说明其表现出严重的心理困境或绝望倾向。  \n' +
          '3. 如果对话只是**轻度的情绪低落、抱怨、焦虑**（如“很烦”“有点焦虑”“不开心”），输出蓝色警报=1，并在解释中说明其表现为轻度的情绪困扰。  \n' +
          '4. 如果未检测到任何负面或危险内容（如“我去上学了”“我吃饭了”），则输出=0，表示没有风险、不需要预警。  \n' +
          '\n' +
          '输出格式（只输出纯 JSON，不要包含任何 Markdown 格式或额外解释）：  \n' +
          '{\n' +
          '  "emotion_flow": "0/1/2/3",\n' +
          '  "alarm_trigger_content": "原始对话内容和触发预警的原因解释"\n' +
          '}\n' +
          '\n' +
          '【用户单轮对话文本】：<<<在这里粘贴文本>>>',
      );

      const parsed = ChatGateway.parse(s);
      if (parsed.emotion_flow > 0) {
        const sessionInfo = await this.sessionService.findSessionInfo(sessionId);
        const userInfo = sessionInfo[0];
        const { phonenumber, userId, parentId } = userInfo;

        await this.alarmService.create({
          userId: parentId,
          childId: userId,
          alarmType: parsed.emotion_flow,
          alarmTriggerContent: parsed.alarm_trigger_content,
        });

        await this.smsService.sendSms(String(phonenumber), '上海智影慧心数字科技', 'SMS_493690377', '');
      }
    } catch (error) {
      this.logger.error('预警分析失败:', error);
    }
  }

  private handleMessage(clientId: string, message: string) {
    try {
      const data = JSON.parse(message);
      this.logger.log(`收到客户端 ${clientId} 的消息:`, data);

      switch (data.type) {
        case 'chat':
          this.handleChatMessage(clientId, data);
          break;
        default:
          this.sendMessage(clientId, {
            type: 'error',
            message: '未知消息类型',
          });
      }
    } catch (error) {
      this.logger.error('消息解析错误:', error);
      this.sendMessage(clientId, {
        type: 'error',
        message: '消息格式错误',
      });
    }
  }

  private async handleChatMessage(clientId: string, data: any) {
    const client = this.clients.get(clientId);
    if (!client || client.readyState !== WebSocket.OPEN) {
      this.logger.warn(`客户端 ${clientId} 不可用`);
      return;
    }

    this.logger.log(`收到客户端 ${clientId} 的消息: ${data.message}`);

    if (!data.message) {
      this.sendMessage(clientId, { type: 'error', message: '消息内容不能为空' });
      return;
    }

    this.sendMessage(clientId, { type: 'processing', message: '正在处理您的请求...' });
    let aiReply = '';
    const createChatDto = data;

    try {
      if (createChatDto.stream) {
        this.clientBuffers.set(clientId, '');

        const sessionInfo = await this.sessionService.findOneById(createChatDto.sessionId);
        if (!sessionInfo) {
          this.sendMessage(clientId, { type: 'error', message: '会话不存在' });
          return;
        }
        // 根据isChild选择不同的聊天服务方法
        const streamPromise = this.chatService.sendParentChatMessage(createChatDto.message, createChatDto.sessionId);

        const stream = await streamPromise; // 等待获取真正的 Readable 流

        // 在handleChatMessage方法中修改stream.on('data'...)部分的逻辑
        stream.on('data', (chunk) => {
          try {
            const rawData = chunk.toString();
            if (rawData.trim() === '[DONE]') {
              this.sendMessage(clientId, { type: 'messageComplete', message: '消息处理完成' });
              this.clientBuffers.delete(clientId);
              return;
            }

            let buffer = this.clientBuffers.get(clientId) || '';
            buffer += rawData;
            const lines = buffer.split('\n');
            buffer = lines.pop() || '';
            this.clientBuffers.set(clientId, buffer);

            for (const line of lines) {
              const trimmedLine = line.trim();
              if (!trimmedLine) continue;

              if (trimmedLine.startsWith('data:')) {
                const jsonStr = trimmedLine.substring('data:'.length).trim();
                if (!jsonStr) continue;

                try {
                  const json = JSON.parse(jsonStr);
                  const content = json.choices[0]?.delta?.content || '';

                  if (content) {
                    aiReply += content;
                    this.sendMessage(clientId, {
                      type: 'messageChunk',
                      id: json.requestId || Date.now().toString(),
                      content: content, // 只发送新增的部分
                      finished: json.stop || false,
                    });
                  }

                  if (json.stop) {
                    this.sendMessage(clientId, { type: 'messageComplete', message: '消息处理完成' });
                    this.clientBuffers.delete(clientId);
                  }
                } catch (parseError) {
                  this.logger.error('解析SSE data字段JSON失败:', parseError.message);
                  this.logger.error('SSE data原始内容:', jsonStr);
                }
              } else if (trimmedLine.startsWith('id:') || trimmedLine.startsWith('event:') || trimmedLine.startsWith('retry:')) {
                this.logger.debug(`跳过SSE控制字段: ${trimmedLine}`);
                continue;
              } else {
                this.logger.warn(`未知SSE行格式: ${trimmedLine}`);
              }
            }
          } catch (processError) {
            this.logger.error('处理数据块时发生错误:', processError.message);
          }
        });

        stream.on('error', (err) => {
          this.logger.error('流式请求发生错误', err);
          this.sendMessage(clientId, { type: 'error', message: '请求处理失败' });
          this.clientBuffers.delete(clientId);
        });

        stream.on('end', async () => {
          // 防止stream提前结束未触发stop标识的情况
          if (this.clientBuffers.has(clientId)) {
            this.sendMessage(clientId, { type: 'messageComplete', message: '消息处理完成' });
            this.clientBuffers.delete(clientId);
          }

          try {
            await this.recordsService.create({
              sessionId: String(createChatDto.sessionId),
              content: createChatDto.message,
              aiReply: aiReply,
            });

            if (createChatDto.isChild === 1) {
              await this.analyzeWarningThreshold(createChatDto.sessionId, createChatDto.message);
            }
          } catch (saveError) {
            this.logger.error('保存会话记录或分析预警时出错:', saveError);
          }
        });
      }
    } catch (error) {
      this.logger.error('处理消息时发生错误', error);
      this.sendMessage(clientId, { type: 'error', message: '处理您的请求时发生错误' });
    }
  }

  sendMessage(clientId: string, message: any) {
    const client = this.clients.get(clientId);
    if (client && client.readyState === WebSocket.OPEN) {
      client.send(JSON.stringify(message));
    }
  }

  broadcast(message: any) {
    const data = JSON.stringify(message);
    this.clients.forEach((client) => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(data);
      }
    });
  }

  onModuleDestroy() {
    this.wss.close(() => {
      this.logger.log('WebSocket 服务器已关闭');
    });
  }
}
